<template>
  <div class="main">
    <div class="map" ref="ref_map"></div>
    <div class="tracks">
      <template v-for="item in state.tracks">
        <div>
          <span :style="{color: item.color}">{{item.infos?.shipName}}</span>
          <template v-if="!item.test">
            <el-button @click="item.focus()">聚焦</el-button>
            <el-button @click="item.show()">显示</el-button>
            <el-button @click="item.hide()">隐藏</el-button>
            <el-color-picker v-model="item.color" @change="() => item.refreshStyle()"/>
          </template>
        </div>
      </template>
    </div>
    <div ref="ref_mapHover" class="hover-info">
      <div class="hover-main">
        <div class="hover-item">
          <div class="hover-item-label">名称：</div>
          <div class="hover-item-value">{{state.mapHover.info?.shipName}}</div>
        </div>
        <div class="hover-item">
          <div class="hover-item-label">时间：</div>
          <div class="hover-item-value">{{state.mapHover.info?.trackTime}}</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {getCurrentInstance, onMounted, reactive, ref} from "vue";
import * as ol from 'ol'
import * as layer from 'ol/layer'
import * as source from 'ol/source'
import * as interaction from 'ol/interaction'
import * as format from "ol/format";
import * as style from "ol/style";
import gcj02Mecator from "@/utils/gcj02Mecator";
import mockJson from './mock.json'
import {getShapeView} from "@/views/map/map-util";
import {_console, randomColor, resetRgbaOpacity} from "@/utils/czr-util";
import ShipTrack from './ShipTrack'
const {proxy} = getCurrentInstance()
const state: any = reactive({
  map: null,
  selected: null,
  tracks: [],
  mapHover: {
    info: {},
    overlay: <any>null
  },
})
const ref_map = ref()
const ref_mapHover = ref()

const initMap = () => {
  state.map = new ol.Map({
    target: ref_map.value,
    layers: [
      new layer.Group({
        layers: [
          new layer.Tile({
            source: new source.XYZ({
              projection: gcj02Mecator,
              url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}'
            }),
          })
        ],
        zIndex: 1
      }),
    ],
    view: new ol.View({
      center: [109.6915958479584, 19.111636735969318],
      projection: 'EPSG:4326', // 设置地图的投影
      zoom: 9
    }),
    interactions: interaction.defaults({
      doubleClickZoom: false,
    })
  })
  state.mapHover.overlay = new ol.Overlay({
    id: 'ref_mapHover',
    element: ref_mapHover.value,
    autoPan: false,
    offset: [0, -30],
    positioning: 'bottom-center',
    stopEvent: true,
  })
  state.map.addOverlay(state.mapHover.overlay)
  // state.map.on('moveend', function (evt) {
  //   console.log(state.map.getView().getZoom())
  // })
  state.map.on('pointermove', (evt) => {
    if (evt.dragging) {
      return;
    }
    if (state.selected !== null) {
      state.selected.set('hover', 0);
      state.selected = null;
    }
    let feature: any = state.map.forEachFeatureAtPixel(evt.pixel, (feature) => {
      return feature;
    },
      {layerFilter: (v) => v.get('layerName')?.includes('_point'), hitTolerance: 0});
    if (feature) {
      feature.set('hover', 1);
      state.selected = feature;
      state.mapHover.info = feature.get('data_')
      state.mapHover.overlay.setPosition(evt.coordinate)
    } else {
      state.mapHover.overlay.setPosition(undefined)
    }
  });
  initTrack()
}
const initTrack = () => {
  const color = '#000000'
  const arr = JSON.parse(JSON.stringify(mockJson.data)).map(v => {
    // v.shipLon += 0.001
    v.shipLat += 0.005
    return v
  })
  let lineWkt = "";
  const webglPoints = []
  arr.forEach((v, i) => {
    if (i === 0) {
      lineWkt += `LINESTRING(${v.shipLon} ${v.shipLat}`;
    } else if (i === arr.length - 1) {
      lineWkt += `,${v.shipLon} ${v.shipLat})`;
    } else {
      lineWkt += `,${v.shipLon} ${v.shipLat}`;
    }
    v.wkt = `POINT(${v.shipLon} ${v.shipLat})`;
    const feat: any = new format.WKT().readFeature(v.wkt)
    feat.set('_data', v)
    webglPoints.push(feat)
  });
  const lS = new source.Vector({
    features: [],
    wrapX: false,
  });
  const lL = new layer.VectorImage({
    source: lS,
    zIndex: 300,
  });
  state.map.addLayer(lL);
  const lineF: any = new format.WKT().readFeature(lineWkt);
  lineF.setStyle(new style.Style({
    stroke: new style.Stroke({
      color: color,
      width: 2,
    }),
  }))
  lS.addFeature(lineF)
  const webglPointLayer = new layer.WebGLPoints({
    zIndex: 400,
    source: new source.Vector({
      features: webglPoints
    }),
    style: {
      'circle-radius': ['match', ['get', 'hover'], 1, 6, 4],
      'circle-fill-color': ['match', ['get', 'hover'], 1, resetRgbaOpacity(color, 0.75), color],
    },
  })
  state.map.addLayer(webglPointLayer)
  getShapeView(state.map, lineF.getGeometry().getCoordinates())
  state.tracks.push({
    test: true,
    color: color,
    lineLayer: lL,
    pointLayer: webglPointLayer,
    shipName: arr[0].shipName,
    show: () => {
      lL.setVisible(true)
      webglPointLayer.setVisible(true)
    },
    hide: () => {
      lL.setVisible(false)
      webglPointLayer.setVisible(false)
    }
  })



  const shipTrack = new ShipTrack({map: state.map, infos: {
    shipName: mockJson.data[0].shipName
  }}).init(mockJson.data)
  state.tracks.push(shipTrack)
}
onMounted(() => {
  initMap()
})
</script>

<style lang="scss" scoped>
.main {
  width: 100%;
  height: 100%;
  position: relative;
  .map {
    position: absolute;
    width: 100%;
    height: 100%;
  }
  .tracks {
    position: absolute;
    top: 0;
    left: 0;
    background-color: #FFFFFF;
    padding: 20px;
  }
}
</style>
